package com.patentbackend.patentmanage.service.lmpl;

import com.patentbackend.patentmanage.dto.PatentDTO;
import com.patentbackend.patentmanage.entity.Patent;
import com.patentbackend.patentmanage.repository.PatentRepository;
import com.patentbackend.patentmanage.service.PatentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Service
public class PatentServiceImpl implements PatentService {

    @Autowired
    private PatentRepository patentRepository;

    @Value("${file.upload-dir}")
    private String uploadDir;

    @Override
    public Patent createPatent(PatentDTO patentDTO) {
        Patent patent = Patent.builder()
                .title(patentDTO.getTitle())
                .patentNumber(patentDTO.getPatentNumber())
                .type(patentDTO.getType())
                .status(patentDTO.getStatus())
                .organization(patentDTO.getOrganization())
                .applicant(patentDTO.getApplicant())
                .inventor(patentDTO.getInventor())
                .applicationDate(patentDTO.getApplicationDate())
                .grantDate(patentDTO.getGrantDate())
                .annualFeeDueDate(patentDTO.getAnnualFeeDueDate())
                .annualFeePaid(patentDTO.getAnnualFeePaid())
                .creatorId(patentDTO.getCreatorId())
                .build();

        return patentRepository.save(patent);
    }

    @Override
    public Patent updatePatent(Long id, PatentDTO patentDTO) {
        Patent patent = patentRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Patent not found with id: " + id));

        if (patentDTO.getTitle() != null) patent.setTitle(patentDTO.getTitle());
        if (patentDTO.getPatentNumber() != null) patent.setPatentNumber(patentDTO.getPatentNumber());
        if (patentDTO.getType() != null) patent.setType(patentDTO.getType());
        if (patentDTO.getStatus() != null) patent.setStatus(patentDTO.getStatus());
        if (patentDTO.getOrganization() != null) patent.setOrganization(patentDTO.getOrganization());
        if (patentDTO.getApplicant() != null) patent.setApplicant(patentDTO.getApplicant());
        if (patentDTO.getInventor() != null) patent.setInventor(patentDTO.getInventor());
        if (patentDTO.getApplicationDate() != null) patent.setApplicationDate(patentDTO.getApplicationDate());
        if (patentDTO.getGrantDate() != null) patent.setGrantDate(patentDTO.getGrantDate());
        if (patentDTO.getAnnualFeeDueDate() != null) patent.setAnnualFeeDueDate(patentDTO.getAnnualFeeDueDate());
        if (patentDTO.getAnnualFeePaid() != null) patent.setAnnualFeePaid(patentDTO.getAnnualFeePaid());

        return patentRepository.save(patent);
    }

    @Override
    public boolean existsById(Long id) {
        return patentRepository.existsById(id);
    }

    @Override
    public Page<Patent> findAll(Pageable pageable) {
        return patentRepository.findAll(pageable);
    }

    @Override
    public Page<Patent> search(String keyword, Pageable pageable) {
        return patentRepository.search(keyword, pageable);
    }

    @Override
    public Optional<Patent> findById(Long id) {
        return patentRepository.findById(id);
    }

    @Override
    public void deletePatent(Long id) {
        patentRepository.deleteById(id);
    }

    @Override
    public String uploadPatentFile(Long patentId, MultipartFile file, String fileType) throws IOException {
        Patent patent = patentRepository.findById(patentId)
                .orElseThrow(() -> new RuntimeException("Patent not found with id: " + patentId));

        // 创建专利文件目录
        Path uploadPath = Paths.get(uploadDir + "/patents/" + patentId);
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }

        // 生成唯一文件名
        String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
        Path filePath = uploadPath.resolve(fileName);

        // 保存文件
        Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);

        // 更新专利文件路径
        switch (fileType.toLowerCase()) {
            case "certificate":
                patent.setCertificatePath("patents/" + patentId + "/" + fileName);
                break;
            case "change_notice":
                patent.setChangeNoticePath("patents/" + patentId + "/" + fileName);
                break;
            case "approval_notice":
                patent.setApprovalNoticePath("patents/" + patentId + "/" + fileName);
                break;
            case "registration_notice":
                patent.setRegistrationNoticePath("patents/" + patentId + "/" + fileName);
                break;
            default:
                throw new IllegalArgumentException("Invalid file type: " + fileType);
        }

        patentRepository.save(patent);

        return "patents/" + patentId + "/" + fileName;
    }

    @Override
    public byte[] downloadFile(String filePath) throws IOException {
        Path fileLocation = Paths.get(uploadDir).resolve(filePath);
        return Files.readAllBytes(fileLocation);
    }

    @Override
    public List<Patent> getAnnualFeeReminders() {
        // 获取当前日期
        Date today = new Date();
        // 计算10天后的日期
        Date tenDaysLater = new Date(today.getTime() + 10 * 24 * 60 * 60 * 1000);

        return patentRepository.findAnnualFeeDueSoon(today, tenDaysLater);
    }
}